import java.util.*; 
import java.io.*;
import edu.vanderbilt.isis.sm.*; 
import edu.vanderbilt.isis.sm.Pseudostate.Kind; 
import edu.vanderbilt.isis.sm.properties.*; 
import com.martiansoftware.jsap.*;
public class TopLevelClock { 
	public StateMachine sm = new StateMachine(); 
	public Interpreter sim; 
	public TopLevelClock() { }
	public static void main(String[] args) throws Exception {
		TopLevelClock example = new TopLevelClock();
		FlaggedOption semantics = new FlaggedOption("semantics")
			.setStringParser(JSAP.STRING_PARSER)
	        .setDefault("SF")
	        .setRequired(false)
	        .setShortFlag('s')
	        .setLongFlag("semantics");
		FlaggedOption dataProviderArg = new FlaggedOption("dataProvider")
			.setStringParser(JSAP.STRING_PARSER)
	        .setDefault("CommandLine")
	        .setRequired(false)
	        .setShortFlag('d')
	        .setLongFlag("dataProvider");
		FlaggedOption maxSteps = new FlaggedOption("maxSteps")
			.setStringParser(JSAP.INTEGER_PARSER)
	        .setDefault("10")
	        .setRequired(false)
	        .setShortFlag(JSAP.NO_SHORTFLAG)
	        .setLongFlag("maxSteps");
		FlaggedOption csvFile = new FlaggedOption("csvFilePath")
			.setStringParser(JSAP.STRING_PARSER)
	        .setDefault("")
	        .setRequired(false)
	        .setShortFlag('c')
	        .setLongFlag("csvFile");
		Switch checkOutputSw = new Switch("checkOutput")
	        .setShortFlag(JSAP.NO_SHORTFLAG)
	        .setLongFlag("checkOutput");
		FlaggedOption looperArg = new FlaggedOption("looper")
			.setStringParser(JSAP.STRING_PARSER)
	        .setDefault("Default")
	        .setRequired(false)
	        .setShortFlag('l')
	        .setLongFlag("looper");
		Switch checkPropertiesSw = new Switch("checkProperties").setShortFlag(
				JSAP.NO_SHORTFLAG).setLongFlag("checkProperties");

		JSAP jsap = new JSAP();
		jsap.registerParameter(semantics);
		jsap.registerParameter(dataProviderArg);
		jsap.registerParameter(csvFile);
		jsap.registerParameter(checkOutputSw);
		jsap.registerParameter(maxSteps);
		jsap.registerParameter(looperArg);
		jsap.registerParameter(checkPropertiesSw);
		JSAPResult config = jsap.parse(args);

		IDataProvider dataProvider = new CommandLineDataProvider();
		IDataPrinter dataPrinter = null;
		ILooper looper = new DefaultLooper();
		List<Pattern> patterns = new ArrayList<Pattern>();

		if (config.getString("dataProvider").toUpperCase().equals("CSV")) {
			String fileName = config.getString("csvFilePath");
			boolean checkOutput = config.getBoolean("checkOutput");
			CSVDataProvider csvDP = new CSVDataProvider(fileName, checkOutput);
			dataProvider = csvDP;
			if (checkOutput){
				dataPrinter = csvDP;
			}
		}
		if (config.getString("dataProvider").toUpperCase().equals("SYMBOLIC")) {
			int steps = config.getInt("maxSteps");
			SymbolicDataProvider sDP = new SymbolicDataProvider(steps);
			dataProvider = sDP;
		}

		if (config.getString("looper").toUpperCase().equals("NONDETERMINISTIC")){
			looper = new NondeterministicLooper();
		}

		if (config.getBoolean("checkProperties")) {
			patterns = example.makeProperties(example.r1.Clock3);
		}

		IDataReader dataReader = new ClockReader(example.r1.Clock3, dataProvider, dataPrinter);
		if (config.getString("semantics").toUpperCase().equals("UML")) {
			example.sim = new UMLInterpreter(example.sm, dataReader, looper);
		}
		else if (config.getString("semantics").toUpperCase().equals("RHAPSODY")) {
			example.sim = new RhapsodyInterpreter(example.sm, dataReader, looper);
		}
		else {
			example.sim = new StateflowInterpreter(example.sm, dataReader, looper, patterns);
		}
		example.sim.getLooper().setInterpreter(example.sim);
		example.initializeTransitions();
		example.DoSim();
}
	public void DoSim() { 
		this.sim.initialize(); 
		this.sim.dataAndEventLoop();
	} 
	public List<Pattern> makeProperties(REGION_T.STATE_T s) { 
		ArrayList<Pattern> patterns = new ArrayList<Pattern>(); 
		return patterns; 
	}
	public class REGION_T extends Region { 
	public REGION_T(IRegionParent parent, int order) { 
		super(parent, order); 
	} 
	public Pseudostate p2 = new Pseudostate(this, Kind.INITIAL);
	public class STATE_T extends State {
	public int time ;
		public STATE_T( String name, Region parent, boolean isFinal ) { 
			super( name, parent, isFinal ); 
		} 
	public class RegionR5 extends Region { 
	public RegionR5(IRegionParent parent, int order) { 
		super(parent, order); 
	} 
	public Pseudostate p1 = new Pseudostate(this, Kind.INITIAL);
	public class StateT5 extends State {
			public StateT5( String name, Region parent, boolean isFinal ) { 
			super( name, parent, isFinal ); 
		} 
	}
	public StateT5 T4 = new StateT5("T", this, false );
	public class Transition5 extends Transition { 
		public Transition5( IVertex source, IVertex target, Region parent, List<Event> triggers, int priority ) {
			super( source, target, parent, triggers, priority);
		}
		public void action(IEventHolder holder) {
			;
		}
		public void conditionAction(IEventHolder holder) {
			;
		}
	}
	ArrayList<Event> triggers6 = new ArrayList<Event>() { {
		add(new Event(""));
	} };
	Transition5 p4 = new Transition5( p1, T4, this, triggers6, 1);
	public class Transition8 extends Transition { 
		public Transition8( IVertex source, IVertex target, Region parent, List<Event> triggers, int priority ) {
			super( source, target, parent, triggers, priority);
		}
		public boolean guard(IEventHolder holder) {
			return time < 15;
		}
		public void action(IEventHolder holder) {
			;
		}
		public void conditionAction(IEventHolder holder) {
			++time;
;
		}
	}
	ArrayList<Event> triggers9 = new ArrayList<Event>() { {
		add(new Event(""));
	} };
	Transition8 p7 = new Transition8( T4, T4, this, triggers9, 1);
}
public RegionR5 r3 = new RegionR5( this, 0 );
	}
	public STATE_T Clock3 = new STATE_T("Clock", this, false );
	Transition p3 = new Transition(p2, Clock3, this, new Event(""));
}
public REGION_T r1 = new REGION_T( sm, 0 );
	public void initializeTransitions() {
	}
}
